﻿#include "DebugWin.h"

#include <QVboxlayout>
#include <QHBoxlayout>
#include <QSpacerItem>
#include <QTableWidgetItem>
#include <QHeaderView>
#include <QFileDialog>
#include <QThread>
#include "QGView.h"
#include "VisionMainWnd.h"
#include "InspectLL.h"
#include <QAbstractEventDispatcher>
#include "Visionapi.h"

DebugWin::DebugWin(QWidget* parent)
{
    createTable();
	init();

    //setParent(parent);
    mainWin_ = (VisionMainWnd*)parent;
}

void DebugWin::init()
{
	// 生成各按钮
	addFile_ = new QPushButton("添加");
	clearFiles_ = new QPushButton("清空");
	stepDebug_ = new QPushButton("单步");
	continueDebug_ = new QPushButton("连续");

	selCam_ = new QComboBox();
    QStringList items;
    items << "cam1" << "cam2";
    selCam_->addItems(items);
	loopCheck_ = new QCheckBox("循环");
	stopPro_ = new QPushButton("停止");

	// 按钮grid布局
	QGridLayout* gridBox = new QGridLayout();
	gridBox->addWidget(addFile_, 0, 0);
	gridBox->addWidget(clearFiles_, 0, 1);
	gridBox->addWidget(stepDebug_, 0, 2);
	gridBox->addWidget(continueDebug_, 0, 3);
	gridBox->addWidget(selCam_, 1, 0);
	gridBox->addItem(new QSpacerItem(0, 0, QSizePolicy::Fixed, QSizePolicy::Fixed), 1, 1);
	gridBox->addWidget(loopCheck_, 1, 2);
	gridBox->addWidget(stopPro_, 1, 3);
	
	// 创建图像文件表格
	////tableImageFiles_ = new QTableWidget(this);
	////tableImageFiles_->setColumnCount(6);

	// 整体布局
	QVBoxLayout* mainBox = new QVBoxLayout(this);
	mainBox->addWidget(tableImageFiles_);
	mainBox->addLayout(gridBox);

    connect(addFile_, SIGNAL(clicked(bool)), this, SLOT(openFiles()));
    connect(clearFiles_, SIGNAL(clicked(bool)), this, SLOT(delTable()));
    connect(stepDebug_, SIGNAL(clicked(bool)), this, SLOT(stepDebug()));
    connect(continueDebug_, SIGNAL(clicked(bool)), this, SLOT(continueDebug()));
    connect(this, SIGNAL(sendToTable(int, double)), this, SLOT(updateTable(int, double)), Qt::BlockingQueuedConnection);
    connect(loopCheck_, SIGNAL(stateChanged(int)), this, SLOT(onCheckBoxStateChanged(int)));
    connect(stopPro_, SIGNAL(clicked(bool)), this, SLOT(stopDebug()));
    connect(selCam_, SIGNAL(activated(int)), this, SLOT(on_itemSelected(int)));
}

void DebugWin::grabOnce()
{
    stepDebug();
}

bool DebugWin::getImageBuffer(cv::Mat& src)
{
    int count = tableImageFiles_->rowCount();
    if (count == 0)
    {
        return false;
    }
    int curRow = tableImageFiles_->currentRow();
    if (curRow < 0 || curRow >= count)
    {
        curRow = 0;
    }

    // 处理:显示
    auto imgName = filesDir_ + "\\" + tableImageFiles_->item(curRow, 0)->text();
    src = cv::imread(imgName.toStdString().c_str(), cv::IMREAD_GRAYSCALE);
    if (src.empty())
    {
        qInfo() << "图像无效";
        return false;
    }

    curRow++;
    tableImageFiles_->setCurrentCell(curRow, QItemSelectionModel::Select);

    return true;
}

void DebugWin::createTable()
{
    tableImageFiles_ = new QTableWidget(this);
    
    tableImageFiles_->setEditTriggers(QAbstractItemView::NoEditTriggers);
    tableImageFiles_->setColumnCount(3);
    tableImageFiles_->setSelectionBehavior(QAbstractItemView::SelectRows);
    tableImageFiles_->setSelectionMode(QAbstractItemView::SingleSelection);

    QFont headerFont = tableImageFiles_->horizontalHeader()->font();
    headerFont.setBold(true);
    tableImageFiles_->horizontalHeader()->setFont(headerFont);

    //设置显示内容
    QStringList headerTitle;
    headerTitle << "文件名" << "状态" << "时间"/* << "其他"*/;
    tableImageFiles_->setHorizontalHeaderLabels(headerTitle);

    tableImageFiles_->setColumnWidth(0, 100);
    tableImageFiles_->setColumnWidth(1, 60);
    tableImageFiles_->setColumnWidth(2, 80);
    ////tableImageFiles_->setColumnWidth(3, 50);
}

void DebugWin::clearTable()
{
    int count = tableImageFiles_->rowCount();
    for (int i = 0; i < count; i++)
    {
        tableImageFiles_->setItem(i, 1, new QTableWidgetItem(""));
    }
}

//#include <QElapsedTimer>
void DebugWin::batchProcess()
{
    stopBatchPro_ = false;
    int curRow = max(0, tableImageFiles_->currentRow());
    int count = tableImageFiles_->rowCount();
    clearTable();

    while (true)
    {
        QElapsedTimer time;
        time.start();

        auto imgName = filesDir_ + "\\" + tableImageFiles_->item(curRow, 0)->text();
        cv::Mat loadImg = cv::imread(imgName.toLocal8Bit().constData(), cv::IMREAD_UNCHANGED);

        QElapsedTimer timeTest;
        timeTest.start();
        //mainWin_->getInferPtr()->infer(loadImg);
        //VisionApi::drawInferResults(loadImg, mainWin_->getInferPtr()->getInferResult()->getResults());
        //double t = (double)timeTest.elapsed();
        //  QImage img(loadImg.data, loadImg.cols, loadImg.rows, loadImg.step, QImage::Format_BGR888);
        //mainWin_->getViews()->DispImage(img, true);
        //mainWin_->getViews()->viewport()->update();

        mainWin_->process_offline(loadImg);
        double t = mainWin_->getInspect()->getInspTime();
        // 离线处理：与ui相关操作都放到该线程，运行稳定无崩溃
        postToThread([this, t] { 
            qInfo() << "inspect time: " << t << "ms";
            updateTable(0, t);
            }); 

      

        curRow = tableImageFiles_->currentRow();
        if (stopBatchPro_ || (curRow == -1 && !loopPro_))
        {
            break;
        }
        if (curRow == -1 && loopPro_)
        {
            curRow = 0;
        }

        // 根据耗时进行计算需要休眠时间
        qint64 elapseTime = time.elapsed();
        int interval_time = int(1000.0 / mainWin_->getFrmRate());  // 能实时改变采集帧率
        if (elapseTime < interval_time)
        {
            QThread::msleep(interval_time - elapseTime);
        }
    }                                   

    curRow = tableImageFiles_->currentRow();
}

void DebugWin::delTable()
{
    tableImageFiles_->clearContents();
    tableImageFiles_->setRowCount(0);
}

void DebugWin::stepDebug()
{
    int count = tableImageFiles_->rowCount();
    if (count == 0)
    {
        return;
    }
    int curRow = tableImageFiles_->currentRow();
    if (curRow < 0 || curRow>=count)
    {
        curRow = 0;
    }

    // 处理:显示
    auto imgName = filesDir_ + "\\" + tableImageFiles_->item(curRow, 0)->text();
    QImage img;
    bool suc = img.load(imgName);
    if (suc)
    {
        cv::Mat loadImg = cv::imread(imgName.toLocal8Bit().constData(), cv::IMREAD_UNCHANGED);
        mainWin_->process_offline(loadImg);
        double t = mainWin_->getInspect()->getInspTime();

        
        //auto infer = mainWin_->getInferPtr();
        /*QElapsedTimer timeTest;
        timeTest.start();
        infer->infer(loadImg);
        double t = timeTest.elapsed();
        VisionApi::drawInferResults(loadImg, infer->getInferResult()->getResults());*/
        //QImage img(loadImg.data, loadImg.cols, loadImg.rows, loadImg.step, QImage::Format_BGR888);
        //mainWin_->getViews()->DispImage(img, true);
        //mainWin_->getViews()->viewport()->update();


        updateTable(0, t);
    }
    
    curRow++;    
    tableImageFiles_->setCurrentCell(curRow, QItemSelectionModel::Select);
}

void DebugWin::continueDebug()
{
    std::thread proThread(&DebugWin::batchProcess, this);
    proThread.detach();
}

void DebugWin::stopDebug()
{
    stopBatchPro_ = true;
}

void DebugWin::onCheckBoxStateChanged(int state)
{
    if (state == Qt::Checked)
    {
        loopPro_ = true;
    }
    else if (state == Qt::Unchecked)
    {
        loopPro_ = false;
    }
}

void DebugWin::updateTable(int signal, double t)
{
    if (signal == 0)
    {
        VisionMainWnd* parent = (VisionMainWnd*)this->window();
        double exeTime = parent->getExeTime(0);

        int curRow = tableImageFiles_->currentRow();
        tableImageFiles_->setItem(curRow, 1, new QTableWidgetItem("(*)"));
        tableImageFiles_->setItem(curRow, 2, new QTableWidgetItem(QString::number(t, 'f', 1) + "ms"));
        tableImageFiles_->setCurrentCell(curRow+1, QItemSelectionModel::Select);
    }
}

void DebugWin::on_itemSelected(int index)
{
    switch (index)
    {
    case 0:
        //qInfo() << "selected cam1";
        selCamIndex_ = 0;
        break;
    case 1:
        //qInfo() << "selected cam2";
        selCamIndex_ = 1;
        break;
    default:
        //qInfo() << "选择错误";
        selCamIndex_ = -1;
        break;
    }
}

void DebugWin::openFiles()
{
    QStringList imageFiles = QFileDialog::getOpenFileNames(this, "打开图像", "",
        "Image Format(*.png *.jpg *.bmp All(*.*))");
    if (imageFiles.isEmpty())
    {
        qDebug() << "文件选择为空！";
        return;
    }

    delTable();

    QFileInfo info(imageFiles.at(0));
    filesDir_ = info.path();

    //mainWin_->getThumbnailList()->addImageItems(imageFiles);
    //mainWin_->pauseGrab(true);
    mainWin_->on_CamCapture();
    
    int imageCount = imageFiles.length();
    for (auto& img : imageFiles)
    {
        int row = tableImageFiles_->rowCount();
        tableImageFiles_->insertRow(row);

        QFileInfo fileInfo(img);
        
        QTableWidgetItem* item = new QTableWidgetItem;
        item->setText(fileInfo.fileName());
        tableImageFiles_->setItem(row, 0, item);
    }

    if (tableImageFiles_->rowCount() > 0)
    {
        tableImageFiles_->setCurrentCell(0, QItemSelectionModel::Select);
    }
}
